/**
  ******************************************************************************
  * File Name          : loralink.c
  * Description        : This file provides code for the configuration
  *                      of the lora e22-400t22s instances.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */
#include "bsp.h"
#if(COLLECTOR_USE_TYPE == COLLECTOR_USE_LORA)
#include "lora.h"
#include "route.h"
#include <stdio.h>
#include <string.h>

/* lora queue define */
QueueHandle_t        LoRa_Recv_qhd = NULL;
static StaticQueue_t lora_recv_que_stru;
static uint8_t       lora_recv_que_area[ LORARECV_QUE_LENGTH * LORARECV_QUE_ITEMSIZE ];

LoRa_BufType  LoRa_RecvBack;
LoRa_BufType  LoRa_RecvIsr;

static uint16_t lora_netid;
//static uint8_t  lora_localid;
static uint8_t  lora_channel;

uint8_t LoRa_Init(void)
{
	LoRa_BspInit();
	
	LoRa_Recv_qhd = xQueueCreateStatic(LORARECV_QUE_LENGTH,
	                                   LORARECV_QUE_ITEMSIZE,
	                                   lora_recv_que_area,
	                                   &lora_recv_que_stru);
	
	if(LoRa_StartUp() == 0)
	{
		SysUsrLog("LoRa: Start success.\r\n");
	}
	else
	{
		SysUsrLog("LoRa: Start fail!\r\n");
	}
	
	/* 在这里计算 netid 和 channel */
	LoRa_DIDtoChannel(ROUTE_SELF_DID, &lora_netid, &lora_channel);
	SysUsrLog("LoRa Net ID : %d\r\n", lora_netid);
	SysUsrLog("LoRa Channel: %d\r\n", lora_channel);
	
	if(LoRa_Config(lora_netid, 0, lora_channel) == 0)
	{
		SysUsrLog("LoRa: Config success.\r\n");
	}
	else
	{
		SysUsrLog("LoRa: Config fail!\r\n");
	}

	vTaskDelay(100);
	
	return 0;
}

static uint8_t lora_link_send(uint8_t dstid, const uint8_t *payload, uint8_t pllen)
{
	uint16_t netid;
  uint8_t sendbuf[20];
  
  if(pllen > 15)
  {
    return 1;
  }
  
	/* 此地址为目标地址 */
	netid = ((lora_netid << 4)& 0xfff0u) + dstid ;
	
	sendbuf[0] = (uint8_t)(netid >> 8);
	sendbuf[1] = (uint8_t)netid;
	
	sendbuf[2] = lora_channel;

	sendbuf[3] = 0x00;   /* 本机地址 */
	
	sendbuf[4] = pllen;
	
	memcpy(sendbuf+5, payload, pllen);
  
  LoRa_UartSendBuf(sendbuf, pllen + 5);
  
  return 0;
}

extern uint8_t LoRa_LinkRecvCallback(uint8_t srcid, const uint8_t *rxpayload, uint8_t pllen);

uint8_t LoRa_LinkLoopback(uint8_t dstid, const uint8_t *payload, uint8_t pllen)
{
	if(pllen > 11)
	{
		return 1;
	}	
	
	memset(&LoRa_RecvBack, 0, sizeof(LoRa_BufType));
	memset(&LoRa_RecvIsr,  0, sizeof(LoRa_BufType));
  xQueueReset(LoRa_Recv_qhd);
  
	if(lora_link_send(dstid, payload, pllen) != 0)
  {
    return 2;
  }
	
	/* waiting for reply */
	if(xQueueReceive(LoRa_Recv_qhd, &LoRa_RecvBack, 3500) == pdTRUE)
	{
		if(LoRa_RecvBack.buf[0] == dstid)
		{
			if(LoRa_RecvBack.buf[1] == (LoRa_RecvBack.count-2))
			{
				if(LoRa_LinkRecvCallback(LoRa_RecvBack.buf[0], LoRa_RecvBack.buf+2, LoRa_RecvBack.buf[1]) == 0)
				{
					return 0;
				}	
			}
		}
	}
	
	return 3;
}

uint8_t LoRa_DIDtoChannel(const char *did, uint16_t *netid, uint8_t *channel)
{
	Route_DidFormatType format;
	
	if(Route_ParseDID(did, &format) != 0)
	{
		return 1;
	}
	
	*netid = (format.sequence / 120)+1;
	
	format.sequence = (format.sequence % 120);
	
	if((format.sequence & 0x01)!=0)
	{
		format.sequence = 64 - ((format.sequence/2)+1);
	}
	else
	{
		format.sequence = 64 + ((format.sequence/2)+1);
	}
	
	if(format.sequence == 18)
	{
		format.sequence = 125;
	}
	
	if(format.sequence == 50)
	{
		format.sequence = 3;
	}
	
	if(format.sequence == 82)
	{
		format.sequence = 126;
	}
	
	if(format.sequence == 114)
	{
		format.sequence = 2;
	}
	
	if(format.sequence > 127)
	{
		return 6;
	}
	
	*channel = format.sequence;

	return 0;
}

#endif /* #if(COLLECTOR_USE_TYPE == COLLECTOR_USE_LORA) */
